function [d, x_bound, ObjFunc, OptSet, precision_init, precision, PopulationSize, MaximalBudget, FileName] = problem_setting(Problem)
%problem_setting: set the problems
%   Problem.FuncType:
%       'EqualMinima','Himmelblau','Sixhump','ModifiedRastrigin','Vincent',
%       'Shubert','Composition','IncreasingMinima','Rastrigin','Schaffer'.
%          .dimension
%          .k (for modified Rastrigin function)
%          .BaseFunc: the id of the base function combinatioin
%              (for composition function): 1, 2, 3, 4
if strcmp(Problem.FuncType,'EqualMinima')
    %% one-dimensional equal minima
    if Problem.dimension ~= 1
        Problem.dimension = 1;
        warning('The dimension of the problem is fixed to 1.')
    end
    d = Problem.dimension;
    x_bound = [0;1];
    OptSet.sol = [0.1;0.3;0.5;0.7;0.9];
    OptSet.fval = 0;
    OptSet.radius = 0.015;
    precision_init = 0.04; % 0.2
    precision = [0.023,0.0075,0.0023,0.00075];
    PopulationSize = 80;
    MaximalBudget = 50000;
    FileName = 'EqualMinima.mat';
elseif strcmp(Problem.FuncType,'Himmelblau')
    %% Himmelblau's function
    if Problem.dimension ~= 2
        Problem.dimension = 2;
        warning('The dimension of the problem is fixed to 2.')
    end
    d = Problem.dimension;
    x_bound = repmat([-6;6],[1,d]);
    OptSet.sol = [3,2;
        -2.805118,3.131312;
        -3.779310,-3.283186;
        3.584428,-1.848126];
    OptSet.fval = 0;
    OptSet.radius = 0.1;
    precision_init = 0.4; % 3.848
    precision = [0.074, 0.024, 0.0074, 0.0024];
    PopulationSize = 80;
    MaximalBudget = 50000;
    FileName = 'Himmelblau.mat';
elseif strcmp(Problem.FuncType,'Sixhump')
    %% Six-hump camel back
    if Problem.dimension ~= 2
        Problem.dimension = 2;
        warning('The dimension of the problem is fixed to 2.')
    end
    d = Problem.dimension;
    x_bound = ([-1.9,1.9;-1.1,1.1])';
    OptSet.fval = -4.12651;
    OptSet.sol = [0.0898207939233943,-0.712627558313027;
        -0.0898442050683038,0.712633095015521];
    OptSet.radius = 0.16;
    precision_init = 0.15; % 1.4
    precision = [0.085, 0.028, 0.0085, 0.0028];
    PopulationSize = 80;
    MaximalBudget = 50000;
    FileName = 'Sixhump.mat';
elseif strcmp(Problem.FuncType,'ModifiedRastrigin')
    %% Modified Rastrigin function
    k = Problem.k;
    if Problem.dimension~=length(k)
        Problem.dimension = length(k);
        warning(['The problem dimension is fixed to ',num2str(length(k)),'.'])
    end
    d = Problem.dimension;
    x_bound = repmat([0;1],[1,d]);
    solutionId = fullfact(k);
    OptSet.sol = (2.*solutionId-1)./2./repmat(k,[prod(k),1]);
    OptSet.fval = d;
    if d == 2
        if sum(k-[3,4])==0
            OptSet.radius = 0.01;
            precision_init = 0.04; % 0.25
            precision = [0.0096, 0.0030, 0.00096, 0.0003];
            PopulationSize = 100;
            MaximalBudget = 200000;
            FileName = 'ModifiedRastrigin34.mat';
        else
            warning('The parameters of the Modified Ratrigin function has not been analyzed.')
        end
    elseif d == 3
        if sum(k-[3,3,3])==0
            OptSet.radius = 0.01;
            precision_init = 0.04; % 0.33
            precision = [0.009, 0.003, 0.0009, 0.0003];
            PopulationSize = 100;
            MaximalBudget = 400000;
            FileName = 'ModifiedRastrigin333.mat';
        else
            warning('The parameters of the Modified Ratrigin function has not been analyzed.')
        end
    elseif d == 5
        if sum(k-[2,2,2,2,2])==0
            OptSet.radius = 0.02;
            precision_init = 0.07; % 0.5
            precision = [0.011, 0.0034, 0.0011, 0.00034];
            PopulationSize = 100;
            MaximalBudget = 400000;
            FileName = 'ModifiedRastrigin22222.mat';
        else
            warning('The parameters of the Modified Ratrigin function has not been analyzed.')
        end
    else
        warning('The parameters of the Modified Ratrigin function has not been analyzed.')
    end
elseif strcmp(Problem.FuncType,'Vincent')
    %% Vincent function
    d = Problem.dimension;
    x_bound = repmat([0.25;10],[1,d]);
    solutionId = fullfact(ones(1,d).*6);
    OptSet.sol = exp((4.*solutionId-11)./20.*pi);
    OptSet.fval = 0;
    OptSet.radius = 0.03;
    precision_init = 0.08; % 0.2912
    precision = [0.03, 0.0096, 0.003, 0.00096];
    PopulationSize = 300;
    if d == 2
        MaximalBudget = 200000;
    elseif  d == 3
        MaximalBudget = 400000;
    else
        warning('The parameters of the selected function has not been analyzed.')
    end
    FileName = ['Vincent',num2str(d),'D.mat'];
elseif strcmp(Problem.FuncType,'Shubert')
    %% Shubert function
    d = Problem.dimension;
    x_bound = repmat([-10;10],[1,d]);
    OptSet.radius = 0.01;
    precision_init = 0.16; % 0.6248
    if d == 2
        OptSet.fval = -186.7309;
        OptSet.sol = [-7.70831,-7.08351; -7.70831,-0.80032; -7.70831,5.48286; -7.08351,-7.70831;
            -7.08351,-1.42513; -7.08351,4.85806; -1.42513,-7.08351; -1.42513,-0.80032;
            -1.42513,5.48286; -0.80032,-7.70831; -0.80032,-1.42513; -0.80032,4.85806;
            4.85806,-7.08351; 4.85806,-0.80032; 4.85806,5.48286; 5.48286,-7.70831;
            5.48286,-1.42513; 5.48286,4.85806];
        precision = [0.0096, 0.003, 0.00096, 0.0003];
        PopulationSize = 100;
        MaximalBudget = 200000;
    elseif d == 3
        OptSet.fval = -2709.0935;
        OptSet.sol = [-7.70831,-7.08351,-7.08351; -7.70831,-7.08351,-0.80032; -7.70831,-7.08351,5.48286;
            -7.70831,-0.80032,-7.08351; -7.70831,-0.80032,-0.80032; -7.70831,-0.80032,5.48286;
            -7.70831,5.48286,-7.08351; -7.70831,5.48286,-0.80032; -7.70831,5.48286,5.48286;
            -7.08351,-7.70831,-7.08351; -7.08351,-7.70831,-0.80032; -7.08351,-7.70831,5.48286;
            -7.08351,-7.08351,-7.70831; -7.08351,-7.08351,-1.42513; -7.08351,-7.08351,4.85806;
            -7.08351,-1.42513,-7.08351; -7.08351,-1.42513,-0.80032; -7.08351,-1.42513,5.48286;
            -7.08351,-0.80032,-7.70831; -7.08351,-0.80032,-1.42513; -7.08351,-0.80032,4.85806;
            -7.08351,4.85806,-7.08351; -7.08351,4.85806,-0.80032; -7.08351,4.85806,5.48286;
            -7.08351,5.48286,-7.70831; -7.08351,5.48286,-1.42513; -7.08351,5.48286,4.85806;
            -1.42513,-7.08351,-7.08351; -1.42513,-7.08351,-0.80032; -1.42513,-7.08351,5.48286;
            -1.42513,-0.80032,-7.08351; -1.42513,-0.80032,-0.80032; -1.42513,-0.80032,5.48286;
            -1.42513,5.48286,-7.08351; -1.42513,5.48286,-0.80032; -1.42513,5.48286,5.48286;
            -0.80032,-7.70831,-7.08351; -0.80032,-7.70831,-0.80032; -0.80032,-7.70831,5.48286;
            -0.80032,-7.08351,-7.70831; -0.80032,-7.08351,-1.42513; -0.80032,-7.08351,4.85806;
            -0.80032,-1.42513,-7.08351; -0.80032,-1.42513,-0.80032; -0.80032,-1.42513,5.48286;
            -0.80032,-0.80032,-7.70831; -0.80032,-0.80032,-1.42513; -0.80032,-0.80032,4.85806;
            -0.80032,4.85806,-7.08351; -0.80032,4.85806,-0.80032; -0.80032,4.85806,5.48286;
            -0.80032,5.48286,-7.70831; -0.80032,5.48286,-1.42513; -0.80032,5.48286,4.85806;
            4.85806,-7.08351,-7.08351; 4.85806,-7.08351,-0.80032; 4.85806,-7.08351,5.48286;
            4.85806,-0.80032,-7.08351; 4.85806,-0.80032,-0.80032; 4.85806,-0.80032,5.48286;
            4.85806,5.48286,-7.08351; 4.85806,5.48286,-0.80032; 4.85806,5.48286,5.48286;
            5.48286,-7.70831,-7.08351; 5.48286,-7.70831,-0.80032; 5.48286,-7.70831,5.48286;
            5.48286,-7.08351,-7.70831; 5.48286,-7.08351,-1.42513; 5.48286,-7.08351,4.85806;
            5.48286,-1.42513,-7.08351; 5.48286,-1.42513,-0.80032; 5.48286,-1.42513,5.48286;
            5.48286,-0.80032,-7.70831; 5.48286,-0.80032,-1.42513; 5.48286,-0.80032,4.85806;
            5.48286,4.85806,-7.08351; 5.48286,4.85806,-0.80032; 5.48286,4.85806,5.48286;
            5.48286,5.48286,-7.70831; 5.48286,5.48286,-1.42513; 5.48286,5.48286,4.85806];
        PopulationSize = 300;
        precision = [0.002, 0.00064, 0.0002, 0.000064];
        MaximalBudget = 400000;
    else
        warning('The parameters of the selected function has not been analyzed.')
    end
    FileName = ['Shubert',num2str(d),'D.mat'];
elseif strcmp(Problem.FuncType,'Composition')
    %% Conposition function
    d = Problem.dimension;
    x_bound = repmat([-5;5],[1,d]);
    if Problem.BaseFunc == 1
        load('composition_data.mat','o')
        Problem.o = o(1:6,1:d);
        Problem.M = repmat(diag(ones(1,d)),[1,1,6]);
        if d == 2
            precision_init = 0.16; % 2.76
            precision = [5E-7,1.6E-8,1.1E-9,3.2E-10];
        else
            warning('The parameters of the selected function has not been analyzed.')
        end
    elseif Problem.BaseFunc == 2
        load('composition_data.mat','o')
        Problem.o = o(1:8,1:d);
        Problem.M = repmat(diag(ones(1,d)),[1,1,8]);
        if d == 2
            precision_init = 0.16; % 2.76
            precision = [1.6E-6,5.6E-8,1.8E-9,5.5E-10];
        else
            warning('The parameters of the selected function has not been analyzed.')
        end
    elseif Problem.BaseFunc == 3
        load('composition_data.mat','o',['M_CF3_',num2str(d),'D'])
        Problem.o = o(1:6,1:d);
        precision_init = 0.02; % 2.76
        if d == 2
            Problem.M = M_CF3_2D;
            precision = [9.5E-8,2E-9,1.5E-10,4.3E-11];
        elseif d == 3
            Problem.M = M_CF3_3D;
            precision = [9E-8,2.5E-9,1.4E-10,3.8E-11];
        elseif d == 5
            Problem.M = M_CF3_5D;
            precision = [1.1E-7,3E-9,1.5E-10,4.2E-11];
        elseif d == 10
            Problem.M = M_CF3_10D;
            precision = [3.8E-8,1.2E-9,1.1E-10,3.2E-11];
        else
            warning('The parameters of the selected function has not been analyzed.')
        end
    elseif Problem.BaseFunc == 4
        load('composition_data.mat','o',['M_CF4_',num2str(d),'D'])
        Problem.o = o(1:8,1:d);
        precision_init = 0.2;
        if d == 3
            Problem.M = M_CF4_3D;
            precision = [5E-9,1.6E-10,1.3E-11,3.8E-12];
        elseif d == 5
            Problem.M = M_CF4_5D;
            precision = [1E-8,3E-10,1.8E-11,4.2E-12];
        elseif d == 10
            Problem.M = M_CF4_10D;
            precision = [7E-9,2E-10,1.4E-11,3.7E-12];
        elseif d == 20
            Problem.M = M_CF4_20D;
            precision = [6E-9,2E-10,1.3E-11,3.5E-12];
        else
            warning('The parameters of the selected function has not been analyzed.')
        end
    else
        error('No such function can be found.')
    end
    OptSet.radius = 0.01;
    OptSet.fval = 0;
    OptSet.sol = Problem.o;
    PopulationSize = 200;
    if d <= 2
        MaximalBudget = 2E5;
    else
        MaximalBudget = 4E5;
    end
    FileName = ['Composition',num2str(Problem.BaseFunc),'_',num2str(d),'D.mat'];
elseif strcmp(Problem.FuncType,'IncreasingMinima')
    %% one-dimensional increasing minima
    if Problem.dimension ~= 1
        Problem.dimension = 1;
        warning('The dimension of the problem is fixed to 1.')
    end
    d = Problem.dimension;
    x_bound = repmat([0.02;1],[1,d]);
    OptSet.fval = [1.84754329279890e-07; 0.0513106897498393;
        0.229184764278421; 0.495888491374641; 0.748389918860396];
    OptSet.sol = [0.0796967889120553; 0.246276975868616;
        0.449497982732034; 0.679163842395897; 0.930151599444996];
    OptSet.radius = 0.01;
    precision_init = 0.02; % 0.2
    precision = [0.017,0.0052,0.0017,0.00052];
    PopulationSize = [];
    MaximalBudget = 1000;
    FileName = 'IncreasingMinima.mat';
elseif strcmp(Problem.FuncType,'Rastrigin')
    %% Rastrigin function
    d = Problem.dimension;
    x_bound = repmat([-5.12;5.12],[1,d]);
    LevelNum = 3;
    level = [0, 0.9949586377, 1.98991223375, 2.984855700];
    solutionId = fullfact(ones(1,d)*(LevelNum*2-1))-LevelNum;
    OptSet.sol = level(abs(solutionId)+1);
    OptSet.sol(solutionId<0) = -OptSet.sol(solutionId<0);
    OptSet.fval = ObjValue(OptSet.sol, Problem);
    [OptSet.fval,rank] = sort(OptSet.fval);
    OptSet.sol = OptSet.sol(rank,:);
    OptSet.radius = 0.1;
    precision_init = 0.1; % 1
    if d == 2
        precision = [0.03, 0.01, 0.003, 0.001];
        MaximalBudget = 30000;
    elseif d == 3
        precision = [0.026, 0.008, 0.0026, 0.0008];
        MaximalBudget = 100000;
    else
        warning('The parameters of the selected function has not been analyzed.')
    end
    PopulationSize = [];
    FileName = ['Rastrigin',num2str(d),'D.mat'];
elseif strcmp(Problem.FuncType,'Schaffer')
    %% Schaffer's function
    if Problem.dimension ~= 2
        Problem.dimension = 2;
        disp('The dimension of the problem is fixed to 2.')
    end
    d = Problem.dimension;
    x_bound = repmat([-10;10],[1,d]);
    OptSet = [];
    precision_init = 0.4; % 1
    precision = [0.4, 0.4, 0.2, 0.08];
    PopulationSize = [];
    MaximalBudget = 1000000;
    FileName = 'Schaffer.mat';
else
    error('No such function can be found.')
end
ObjFunc = @(x)ObjValue(x, Problem);
end

